package com.loyal.rx;

import com.loyal.client.RxClient;
import com.loyal.client.RxConfig;
import com.loyal.client.download.ProgressImpl;
import com.loyal.client.download.ProgressInterceptor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.http.GET;
import retrofit2.http.Streaming;
import retrofit2.http.Url;

public class DownloadAPI {
    private RetroManager retrofitManage;

    private static final String baseUrl = "http://192.168.0.1:9080/command/";

    public static DownloadAPI getInstance(ProgressImpl listener) {
        return new DownloadAPI(listener);
    }

    private DownloadAPI(ProgressImpl listener) {
        ProgressInterceptor interceptor = new ProgressInterceptor(listener);
        OkHttpClient.Builder okctBuilder = RxClient.getInstance().getOkCtBuilder();
        okctBuilder.addInterceptor(interceptor);//应用拦截器

        RxConfig rxConfig = new RxConfig();
        rxConfig.setUrl(baseUrl);
        rxConfig.setOkCtBuilder(okctBuilder);

        retrofitManage = RetroManager.getInstance();
        retrofitManage.build(rxConfig);
    }

    public ApiService getDownService() {
        return retrofitManage.createServer(ApiService.class);
    }

    public static void saveFile(Observable<ResponseBody> observable, final File file, final Observer<InputStream> observer) {
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .map(ResponseBody::byteStream
                ).observeOn(Schedulers.computation())
                .doOnNext(inputStream -> {
                    try {
                        writeFile(inputStream, file);
                    } catch (Exception e) {
                        observer.onError(e);
                    }
                }).observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    private static void writeFile(InputStream in, File file) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(file)) {
            byte[] buffer = new byte[1024 * 128];
            int len;
            while ((len = in.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != in)
                in.close();
        }
    }

    public interface ApiService {

        @Streaming
        @GET
        Observable<ResponseBody> download(@Url String url);
    }
}